//
//  AudioTranscriptionManager.swift
//  GLUZSwift
//
//  Created by xyanl on 2025/3/29.
//
// 科大讯飞 接口调用流程
// https://www.xfyun.cn/doc/asr/rtasr/API.html#接口调用流程
// 实时音频转写，翻译
import UIKit
import SocketRocket

protocol AudioTranscriptionDelegate {
    
    /// 语音识别出来的最终结果的文本text, 翻译成目标语言(如:英语)的文本 translatedText
    /// - Parameters:
    ///   - text: 语音识别出的文本
    ///   - translatedText: 转成目标语言的文本
    func onRecognizedText(text: String, translatedText: String)
    
    
    /// 关闭 webSocket
    /// - Parameters:
    ///   - code: code description
    ///   - reason: 原因
    func didClose(code: Int, reason: String)
    
}

class AudioTranscriptionManager: NSObject {
    
    // 语音的语言
    var fromLanguage: String = ""
    // 需要被翻译成的语言，如果不传，则不需要翻译
    var toLanguage: String = ""
    
    let appId: String = "9b1b2dfd"
    let appKey: String = "e7590b1bc5a3de12928515f19e912356"
    
    var webSocket: SRWebSocket?
    
    var delegate: AudioTranscriptionDelegate?
    
}

extension AudioTranscriptionManager {
    
    func connectWebSocket() {
        // 科大讯飞 接口调用流程
        // https://www.xfyun.cn/doc/asr/rtasr/API.html#接口调用流程
        
        // 签名元组
        let signaTuple = SparkChainConfig.createSigna(appId: appId, appKey: appKey)
        // 时间戳
        let timestamp = signaTuple.0
        xLog("[WebSocket] timestamp : \(timestamp)")
        let signa = signaTuple.1
        xLog("[WebSocket] signa : \(signa)")
        
        let parames = [
            "appid": appId,
            "ts": timestamp,
            "signa": signa,
            "transStrategy": "2",
            "lang": fromLanguage
        ]
        
//        if !toLanguage.isEmpty {
//            // 需要翻译
//            parames["transType"] = "normal"
//            parames["targetLang"] = toLanguage
//        }
        
        let url = "ws://rtasr.xfyun.cn/v1/ws?" + parames.toQueryString()!
        
        if let uRL = URL(string: url) {
            xLog("[WebSocket] 启动 \(url)")
            webSocket = SRWebSocket(url: uRL)
            webSocket!.delegate = self
            webSocket!.open()
            
        } else {
            xLog("[WebSocket] 启动失败")
        }
    }
    
    /// 断线重连
    func reconnectWebSocket() {
        webSocket?.close()
        webSocket = nil
        DispatchQueue.main.asyncAfter(wallDeadline: .now() + 1) { [weak self] in
            self?.connectWebSocket()
        }
    }
    
    /// 关闭 WebSocket
    func closeWebSocket() {
        guard let webSocket = webSocket else { return }
        webSocket.close()
        self.webSocket = nil
    }
    
    
    /// 发送音频数据（每40ms发送1280字节）
    func sendAudioData(data: Data) {
        guard let webSocket = webSocket else { return }
        if webSocket.readyState == .OPEN {
            try! webSocket.send(data: data)
        }
    }
    
    
    /// 解析语音转写文字
    private func parseTranslationMiddleMessage(_ jsonString: String) {
        guard let jsonDic = jsonString.toDictionary() else {
            return
        }
        
        let cnDic = jsonDic["cn"] as! [String: Any]
        let stDic = cnDic["st"] as! [String: Any]
        let type = stDic["type"] as! String
        if type == "1" {
            // 中间过程，不处理
            return
        }
        
        let rtArr = stDic["rt"] as! [[String: Any]]
        var result = ""
        
        for rtDic in rtArr {
            let wsArr = rtDic["ws"] as! [[String: Any]]
            for wsDic in wsArr {
                let cwArr = wsDic["cw"] as! [[String: Any]]
                for cwDic in cwArr {
                    let word = cwDic["w"] as! String
                    let wp = cwDic["wp"] as! String
                    // n-普通词；s-顺滑词（语气词）；p-标点
                    if wp != "p" {
                        // 标点符号 过滤掉
                        result.append(word)
                    }
                }
            }
        }
        
        xLog("[WebSocket] 翻译结果：\(result)")
        
        delegate?.onRecognizedText(text: result, translatedText: "")
        
    }
    
    /// 解析语音转写文字，并翻译
    private func parseTranslationMessage(_ jsonString: String) {
        guard let jsonDic = jsonString.toDictionary() else {
            return
        }
        
        // 打印解析结果
        guard let src = jsonDic["src"] as? String else {
            return
        }
        guard let dst = jsonDic["dst"] as? String else {
            return
        }
        
        xLog("------- 打印解析结果 -------")
        xLog("源文本: \(src)")
        xLog("翻译结果：\(dst)")
        
        delegate?.onRecognizedText(text: src, translatedText: dst)
    }
    
}

// MARK: - SRWebSocketDelegate
extension AudioTranscriptionManager: SRWebSocketDelegate {
    
    func webSocketDidOpen(_ webSocket: SRWebSocket) {
        xLog("[WebSocket] 连接成功")
    }
    
    func webSocket(_ webSocket: SRWebSocket, didReceiveMessage message: Any) {
        // xLog("[WebSocket] 收到消息：\(message)")
        
        let msg = message as! String
        guard let msgDic = msg.toDictionary() else {
            return
        }
        
        // 获取 action 类型
        let action = msgDic["action"] as! String
        // 根据 action 处理不同逻辑
        if action == "started" {
            // 握手成功
            let sid = msgDic["sid"]
            xLog("[WebSocket] 握手成功！sid: \(sid ?? "nil")")
        } else  if action == "result" {
            // 处理转写结果
            let data = msgDic["data"] as! String
            parseTranslationMiddleMessage(data)
//            if toLanguage.isEmpty {
//                parseTranslationMiddleMessage(data)
//            } else {
//                parseTranslationMessage(data)
//            }
            
            
        } else  if action == "error" {
            // 处理错误
            xLog("[WebSocket] Error: \(msg)")
        }
        
    }
    
    // WebSocket 关闭 （调用 close 或超时后关闭）
    func webSocket(_ webSocket: SRWebSocket, didCloseWithCode code: Int, reason: String?, wasClean: Bool) {
        xLog("[WebSocket] 断开连接 code：\(code)，原因： \(reason ?? "nil")")
        self.webSocket = nil
        delegate?.didClose(code: code, reason: reason ?? "nil")
        DispatchQueue.main.asyncAfter(wallDeadline: .now() + 1) {
            self.reconnectWebSocket()
        }
    }
    
    // WebSocket 连接失败
    func webSocket(_ webSocket: SRWebSocket, didFailWithError error: any Error) {
        xLog("[WebSocket] 连接失败 error：\(error.localizedDescription)")
    }
    
    
}
